package depots

// 请求
type DingDong struct {
	Request DingDong_Request `json:"request"`
	Session DingDong_Session `json:"session"`
	Version string           `json:"version"`
}

type DingDong_Session struct {
	IsNew       bool                   `json:"isNew"`
	SessionId   string                 `json:"sessionId"`
	Contexts    map[string]interface{} `json:"contexts"`
	Application map[string]interface{} `json:"contexts"`
	User        DingDong_SessionUser   `json:"user"`
	Device      map[string]interface{} `json:"device"`
}

type DingDong_SessionUser struct {
	UserId      string `json:"userId"`
	AccessToken string `json:"accessToken"`
}

type DingDong_Request struct {
	Type        string                       `json:"type"`
	RequestId   string                       `json:"requestId"`
	Timestamp   int64                        `json:"timestamp"`
	DialogState string                       `json:"dialogState"`
	Intent      DingDong_RequestIntent       `json:"intent"`
	Reason      DingDong_RequestIntentReason `json:"reason"`
}

type DingDong_RequestIntent struct {
	Name          string                                `json:"name"`
	ConfirmResult string                                `json:"confirmResult"`
	Slots         map[string]DingDong_RequestIntentSlot `json:"slots"`
}

type DingDong_RequestIntentSlot struct {
	Name          string `json:"name"`
	Value         string `json:"value"`
	Matched       bool   `json:"matched"`
	ConfirmResult string `json:"confirmResult"`
}

type DingDong_RequestIntentReason struct {
	Type    string `json:"type"`
	Message string `json:"message"`
}

// 响应
type DingDong_Response struct {
	Version          string                               `json:"version"`          // 协议版本号，当前为“1.0”版本
	Contexts         map[string]interface{}               `json:"contexts"`         // 技能存储会话上下文数据的空间，下次请求会带回当前响应存放的键值对数据，在不同会话中也是有效的。格式为 "contexts": {key : value}
	Response         map[string]DingDong_ResponseStandard `json:"response"`         // 响应内容，可以返回组合的内容。响应内容有以下几种： 1.标准响应
	Directives       []interface{}                        `json:"directives"`       // 指令集合，可以存放多条指令。指令类型有以下几种 1.对话指令 2.音频控制指令 3.京东接口指令
	ShouldEndSession bool                                 `json:"shouldEndSession"` // 是否结束会话，设置为false后，用户可以继续对话。
}

type DingDong_ResponseStandard struct {
	Type string `json:"type"` // 文本类型，简单文本"PlainText"
	Text string `json:"text"`
}

// 指令 Dialog.ElicitSlot 向用户询问某一个槽位的值。
type DingDong_Dialog struct {
	Type     string      `json:"type"`
	SlotName string      `json:"slotName"`
	Intent   interface{} `json:"intent"`
}

type DingDong_DialogIntent struct {
	Name          string `json:"name"`
	Slots         map[string]interface{}
	ConfirmResult string `json:"confirmResult"`
}

// @title 回应 output
// @param text string true 回应文字
func (intent *DingDong) Answer(text string) *DingDong_Response {
	res := &DingDong_Response{
		Version: "1.0",
		Response: map[string]DingDong_ResponseStandard{
			"output": DingDong_ResponseStandard{
				Type: "PlainText",
				Text: text,
			},
		},
		ShouldEndSession: true,
	}
	return res
}

// @title 是否结束会话
func (res *DingDong_Response) EndSession(b bool) *DingDong_Response {
	res.ShouldEndSession = b
	return res
}

// @title 重新提示用户的文本信息
// @param text string true 重新提示文字
func (res *DingDong_Response) Reprompt(text string) *DingDong_Response {
	res.Response["reprompt"] = DingDong_ResponseStandard{
		Type: "PlainText",
		Text: text,
	}
	return res
}

// @title  向用户询问某一个槽位的值。
// @param intentName string true 意图名字
// @param slotName string true 询问槽位名字
func (res *DingDong_Response) ElicitSlot(intentName, slotName string) *DingDong_Response {
	intent := DingDong_DialogIntent{
		ConfirmResult: "NONE",
		Name:          intentName,
		Slots: map[string]interface{}{
			slotName: map[string]interface{}{
				"name": slotName,
			},
		},
	}
	dialog := DingDong_Dialog{
		Type:     "Dialog.ElicitSlot",
		SlotName: slotName,
		Intent:   intent,
	}
	res.Directives = append(res.Directives, dialog)
	res.ShouldEndSession = false
	return res
}

// @title 获取槽位信息
func (intent *DingDong) GetSlot(slotName string) *DingDong_RequestIntentSlot {
	if slot, ok := intent.Request.Intent.Slots[slotName]; ok {
		return &slot
	}
	return nil
}
